package com.afdor.rws.event.channel.jedis.sharded;

import com.afdor.rws.annotation.extension.Extension;
import com.afdor.rws.event.Event;
import com.afdor.rws.event.channel.client.consumer.handler.EventRetryStrategy;
import com.afdor.rws.event.channel.jedis.JedisUtils;
import com.afdor.rws.event.config.EventConfigUtils;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.ToString;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import redis.clients.jedis.ShardedJedis;

/**
 * Jedis事件重试策略
 *
 * @author 悭梵
 * @date Created in 2018-08-21 10:29
 */
@ToString
@EqualsAndHashCode
@NoArgsConstructor
@Extension(value = "jedis", order = Extension.NORMAL_ORDER - 100, scope = Extension.Scope.PROTOTYPE, interfaceClass = EventRetryStrategy.class)
public class JedisEventRetryStrategy implements EventRetryStrategy {

    @Getter
    private ShardedJedisEventConsumer shardedJedisEventConsumer;

    public JedisEventRetryStrategy(ShardedJedisEventConsumer shardedJedisEventConsumer) {
        this();
        setShardedJedisEventConsumer(shardedJedisEventConsumer);
    }

    public JedisEventRetryStrategy setShardedJedisEventConsumer(ShardedJedisEventConsumer shardedJedisEventConsumer) {
        this.shardedJedisEventConsumer = shardedJedisEventConsumer;
        return this;
    }

    public String getRetryResult() {
        ShardedJedis jedis = shardedJedisEventConsumer.getShardedJedisPool().getResource();
        try {
            return getRetryResult(jedis);
        } finally {
            jedis.close();
        }
    }

    public String getRetryResult(ShardedJedis jedis) {
        return jedis.lpop(JedisUtils.getRetryQueueName(shardedJedisEventConsumer.getEventSourceName()));
    }

    @Override
    public void retry(@NonNull Event event) {
        ShardedJedis jedis = shardedJedisEventConsumer.getShardedJedisPool().getResource();
        try {
            retry(event, jedis);
        } finally {
            jedis.close();
        }
    }

    /**
     * 重试消息
     *
     * @param event
     * @param jedis
     */
    protected void retry(@NonNull Event event, ShardedJedis jedis) {
        /* 自动场景执行中 */
        if (StringUtils.equalsAny(event.getStatus().name(), Event.Status.EXECUTION.name())) {
            int retryNum = NumberUtils.createInteger(EventConfigUtils.getProperty(EventConfigUtils.EVENT_CONSUMER_MAX_RETRY_NUM, "3"));
            if (event.getRetryCount() >= retryNum) {
                event.setStatus(Event.Status.FAILURE_END);
            } else {
                event.addRetry();
                event.setStatus(Event.Status.FAILURE);
                jedis.lpush(JedisUtils.getRetryQueueName(event.getEventSourceName()), shardedJedisEventConsumer.getSerialization().serialize(event).toString());
            }
            event.persistence();
        } else if (StringUtils.equalsAny(event.getStatus().name(), Event.Status.MANUAL_EXECUTION.name())) {
            event.setStatus(Event.Status.MANUAL_FAILURE);
            event.persistence();
        } else {
            event.persistence();
        }
    }


}
